/*
 * Copyright 2015 泛泛o0之辈
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.jfast.framework.upload;

import cn.jfast.framework.base.prop.CoreConsts;

import javax.servlet.http.HttpServletRequest;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;

public class FileRequestResolver implements MultiPartRequest{

	private Map<String,List<UploadFile>> fileMap = new ConcurrentHashMap<String,List<UploadFile>>();
	private Map<String,List<String>> attrMap = new ConcurrentHashMap<String,List<String>>();
	private Vector<String> attrNames = new Vector<String>();
	private Map<String,String[]> requestParamMap = new ConcurrentHashMap<String,String[]>();
	private UploadFile file;

	private static final String SIGN_MULTIDATA = "multipart/form-data";

	public static boolean isMultipart(HttpServletRequest request) {
		String contentType = request.getContentType();
		if (contentType != null && !contentType.isEmpty()) {
			if (contentType.indexOf(SIGN_MULTIDATA) >= 0) {
				return true;
			}
		}
		return false;
	}

	public MultiPartRequest resolveMultipart(HttpServletRequest request)
			throws IOException {

		if (!isMultipart(request)) {
			return this;
		}
		requestParamMap.putAll(request.getParameterMap());
		InputStream input = request.getInputStream();

		String charset = MultiRequestFieldAnalizer.getCharset(request);

		String boundarys = MultiRequestFieldAnalizer.getBoundaryStr(request);

		Iterator<UploadFile> uploadFiles = new UploadFileIterator(input,
				charset, boundarys.getBytes(charset));

		while (uploadFiles.hasNext()) {
			file = uploadFiles.next();
			if(!attrNames.contains(file.getFieldName()))
				attrNames.add(file.getFieldName());
			if (null == file.getFileName()) {
				if(!attrMap.containsKey(file.getFieldName())){
					attrMap.put(file.getFieldName(), new ArrayList<String>());
				}
				attrMap.get(file.getFieldName()).add(URLDecoder.decode(new String(file.getFileData(),CoreConsts.encoding), CoreConsts.encoding));
			} else {
				if(!fileMap.containsKey(file.getFieldName())){
					fileMap.put(file.getFieldName(), new ArrayList<UploadFile>());
				}
				fileMap.get(file.getFieldName()).add(file);
			}
		}
		return this;
	}

	public Map<String,List<UploadFile>> getFileMap() {
		return this.fileMap;
	}

	public Map<String, List<String>> getAttrMap() {
		return this.attrMap;
	}

	public Enumeration<String> getAttrNames() {
		return attrNames.elements();
	}

	public String getAttr(String fieldName) {
		List<String> attrs = this.attrMap.get(fieldName);
		if(null == attrs)
			return null;
		String[] val = attrs.toArray(new String[]{});
		if(val.length > 1)
			throw new RuntimeException("param ["+fieldName+"] has multi values");
		else if(val.length == 1)
			return val[0];
		else 
			return null;
	}
	
}
